home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / xdsn217.zip / SAMPLES / SIMPLE / linnew.mod < prev    next >
Text File  |  1996-07-10  |  26KB  |  903 lines

  1. <* IF __GEN_X86__ THEN *>
  2.   <*+NOPTRALIAS*>
  3.   <*-SPACE*>
  4.   <*-GENHISTORY*>
  5.   <*+DOREORDER*>
  6. <* END *>
  7. <* ALIGNMENT="4"*>
  8. <*+PROCINLINE*>
  9. <*-CHECKINDEX*>
  10. <*-CHECKRANGE*>
  11. <*-CHECKNIL*>
  12. <*-IOVERFLOW*>
  13. <*-COVERFLOW*>
  14. <*-GENDEBUG*>
  15. <*-LINENO*>
  16.  
  17. <* IF NOT DEFINED (DP) THEN *>
  18. <* NEW DP+ *>
  19. <* END *>
  20.  
  21. MODULE linnew;
  22.  
  23. IMPORT SYSTEM;
  24. IMPORT SysClock;
  25. FROM STextIO IMPORT WriteString, ReadString, WriteLn, SkipLine;
  26. FROM <* IF DP THEN *> SLongIO <* ELSE *> SRealIO <* END *> IMPORT WriteFixed;
  27. FROM SWholeIO IMPORT WriteInt;
  28. FROM WholeStr IMPORT StrToInt;
  29. FROM ConvTypes IMPORT ConvResults;
  30. FROM Storage IMPORT ALLOCATE, DEALLOCATE;
  31.  
  32. (*
  33. **
  34. ** LINPACK.C        Linpack benchmark, calculates FLOPS.
  35. **                  (FLoating Point Operations Per Second)
  36. **
  37. ** Translated to C by Bonnie Toy 5/88
  38. **
  39. ** Modified by Will Menninger, 10/93, with these features:
  40. **  (modified on 2/25/94  to fix a problem with daxpy for
  41. **   unequal increments or equal increments not equal to 1.
  42. **     Jack Dongarra)
  43. **
  44. ** - Defaults to double precision.
  45. ** - Averages ROLLed and UNROLLed performance.
  46. ** - User selectable array sizes.
  47. ** - Automatically does enough repetitions to take at least 40 CPU seconds.
  48. ** - Prints machine precision.
  49. ** - ANSI prototyping.
  50. **
  51. ** To compile:  cc -O -o linpack linpack.c -lm
  52. **
  53. **
  54. *)
  55.  
  56. <* IF DP THEN *>
  57.  
  58. CONST PREC      = "Double";
  59.       BASE10DIG = 14; (* DBL_DIG; *)
  60.  
  61. TYPE FLOAT = LONGREAL;
  62.  
  63. <* ELSE *>
  64.  
  65. CONST PREC      = "Single";
  66.       BASE10DIG = 7; (* FLT_DIG; *)
  67.  
  68. TYPE FLOAT = REAL;
  69.  
  70. <* END *>
  71.  
  72. TYPE 
  73.     FLOATARRAY    = ARRAY [0..10000000] OF FLOAT;
  74.     INTARRAY      = ARRAY [0..10000000] OF INTEGER;
  75.     FLOATARRAYPTR = POINTER TO FLOATARRAY;
  76.     INTARRAYPTR   = POINTER TO INTARRAY;
  77.  
  78. (*
  79. ** Constant times a vector plus a vector.
  80. ** Jack Dongarra, linpack, 3/11/78.
  81. ** ROLLED version
  82. *)
  83.  
  84. PROCEDURE daxpy_r (n : INTEGER; da : FLOAT;
  85.                    VAR dx : FLOATARRAY; incx : INTEGER;
  86.                    VAR dy : FLOATARRAY; incy : INTEGER);
  87.  
  88. VAR i,ix,iy : INTEGER;
  89. BEGIN
  90.     IF n <= 0   THEN RETURN END;
  91.     IF da = 0.0 THEN RETURN END;
  92.  
  93.     IF (incx <> 1) OR (incy <> 1) THEN
  94.  
  95.         (* code for unequal increments or equal increments <> 1 *)
  96.  
  97.         ix := 1;
  98.         iy := 1;
  99.         IF incx < 0 THEN ix := (-n+1)*incx + 1; END;
  100.         IF incy < 0 THEN iy := (-n+1)*incy + 1; END;
  101.         FOR i := 0 TO n-1 DO
  102.             dy[iy] := dy[iy] + da*dx[ix];
  103.             INC (ix, incx);
  104.             INC (iy, incy);
  105.         END;
  106.         RETURN;
  107.     END;
  108.  
  109.     (* code for both increments equal to 1 *)
  110.  
  111.     FOR i := 0 TO n-1 DO
  112.         dy[i] := dy[i] + da*dx[i];
  113.     END;
  114. END daxpy_r;
  115.  
  116. (*
  117. ** Forms the dot product of two vectors.
  118. ** Jack Dongarra, linpack, 3/11/78.
  119. ** ROLLED version
  120. *)
  121.  
  122. PROCEDURE ddot_r (n : INTEGER; VAR dx : FLOATARRAY; incx : INTEGER;
  123.                                VAR dy : FLOATARRAY; incy : INTEGER) : FLOAT;
  124.  
  125. VAR dtemp : FLOAT;
  126.     i,ix,iy : INTEGER;
  127. BEGIN
  128.     dtemp := 0.0;
  129.  
  130.     IF n <= 0 THEN RETURN 0.0; END;
  131.     IF (incx <> 1) OR (incy <> 1) THEN
  132.  
  133.         (* code for unequal increments or equal increments <> 1 *)
  134.  
  135.         ix := 0;
  136.         iy := 0;
  137.         IF incx < 0 THEN ix := (-n+1)*incx; END;
  138.         IF incy < 0 THEN iy := (-n+1)*incy; END;
  139.         FOR i := 0 TO n-1 DO
  140.             dtemp := dtemp + dx[ix]*dy[iy];
  141.             INC (ix, incx);
  142.             INC (iy, incy);
  143.         END;
  144.         RETURN dtemp;
  145.     END;
  146.  
  147.     (* code for both increments equal to 1 *)
  148.  
  149.     FOR i:=0 TO n-1 DO
  150.         dtemp := dtemp + dx[i]*dy[i];
  151.     END;
  152.     RETURN dtemp;
  153. END ddot_r;
  154.  
  155.  
  156. (*
  157. ** Scales a vector by a constant.
  158. ** Jack Dongarra, linpack, 3/11/78.
  159. ** ROLLED version
  160. *)
  161.  
  162. PROCEDURE dscal_r (n : INTEGER; da : FLOAT;
  163.                    VAR dx : FLOATARRAY; incx : INTEGER);
  164.  
  165. VAR i : INTEGER;
  166. BEGIN
  167.     IF n <= 0 THEN RETURN END;
  168.     IF incx <> 1 THEN
  169.  
  170.         (* code for increment not equal to 1 *)
  171.  
  172.         FOR i := 0 TO n-1 DO
  173.             dx[i*incx] := da*dx[i*incx];
  174.         END;
  175.         RETURN;
  176.     END;
  177.  
  178.     (* code for increment equal to 1 *)
  179.  
  180.     FOR i := 0 TO n-1 DO
  181.         dx[i] := da*dx[i];
  182.     END;
  183. END dscal_r;
  184.  
  185. (*
  186. ** constant times a vector plus a vector.
  187. ** Jack Dongarra, linpack, 3/11/78.
  188. ** UNROLLED version
  189. *)
  190.  
  191. PROCEDURE daxpy_ur (n : INTEGER; da : FLOAT;
  192.                     VAR dx : FLOATARRAY; incx : INTEGER;
  193.                     VAR dy : FLOATARRAY; incy : INTEGER);
  194.  
  195. VAR i,ix,iy,m : INTEGER;
  196. BEGIN
  197.     IF n <= 0   THEN RETURN END;
  198.     IF da = 0.0 THEN RETURN END;
  199.  
  200.     IF (incx <> 1) OR (incy <> 1) THEN
  201.  
  202.         (* code for unequal increments or equal increments <> 1 *)
  203.  
  204.         ix := 1;
  205.         iy := 1;
  206.         IF incx < 0 THEN ix := (-n+1)*incx + 1; END;
  207.         IF incy < 0 THEN iy := (-n+1)*incy + 1; END;
  208.         FOR i := 0 TO n-1 DO
  209.             dy[iy] := dy[iy] + da*dx[ix];
  210.             INC (ix, incx);
  211.             INC (iy, incy);
  212.         END;
  213.         RETURN;
  214.     END;
  215.  
  216.     (* code for both increments equal to 1 *)
  217.  
  218.     m := n MOD 4;
  219.     IF m <> 0 THEN
  220.         FOR i := 0 TO m-1 DO
  221.             dy[i] := dy[i] + da*dx[i];
  222.         END;
  223.         IF n < 4 THEN
  224.             RETURN;
  225.         END;
  226.     END;
  227.     FOR i := m TO n-1 BY 4 DO
  228.         dy[i]   := dy[i] + da*dx[i];
  229.         dy[i+1] := dy[i+1] + da*dx[i+1];
  230.         dy[i+2] := dy[i+2] + da*dx[i+2];
  231.         dy[i+3] := dy[i+3] + da*dx[i+3];
  232.     END;
  233. END daxpy_ur;
  234.  
  235. (*
  236. ** Forms the dot product of two vectors.
  237. ** Jack Dongarra, linpack, 3/11/78.
  238. ** UNROLLED version
  239. *)
  240.  
  241. PROCEDURE ddot_ur (n : INTEGER;
  242.                    VAR dx : FLOATARRAY; incx : INTEGER;
  243.                    VAR dy : FLOATARRAY; incy : INTEGER) : FLOAT;
  244.  
  245. VAR dtemp : FLOAT;
  246.     i,ix,iy,m : INTEGER;
  247. BEGIN
  248.     dtemp := 0.0;
  249.  
  250.     IF n <= 0 THEN RETURN 0.0; END;
  251.  
  252.     IF (incx <> 1) OR (incy <> 1) THEN
  253.  
  254.         (* code for unequal increments or equal increments != 1 *)
  255.  
  256.         ix := 0;
  257.         iy := 0;
  258.         IF incx < 0 THEN ix := (-n+1)*incx; END;
  259.         IF incy < 0 THEN iy := (-n+1)*incy; END;
  260.         FOR i := 0 TO n-1 DO
  261.             dtemp := dtemp + dx[ix]*dy[iy];
  262.             INC (ix, incx);
  263.             INC (iy, incy);
  264.         END;
  265.         RETURN dtemp;
  266.     END;
  267.  
  268.     (* code for both increments equal to 1 *)
  269.  
  270.     m := n MOD 5;
  271.     IF m <> 0 THEN
  272.         FOR i := 0 TO m-1 DO
  273.             dtemp := dtemp + dx[i]*dy[i];
  274.         END;
  275.         IF n < 5 THEN
  276.             RETURN dtemp;
  277.         END;
  278.     END;
  279.     FOR i := m TO n-1 BY 5 DO
  280.         dtemp := dtemp + dx[i]*dy[i] +
  281.                          dx[i+1]*dy[i+1] +
  282.                          dx[i+2]*dy[i+2] +
  283.                          dx[i+3]*dy[i+3] +
  284.                          dx[i+4]*dy[i+4];
  285.     END;
  286.     RETURN dtemp;
  287. END ddot_ur;
  288.  
  289.  
  290. (*
  291. ** Scales a vector by a constant.
  292. ** Jack Dongarra, linpack, 3/11/78.
  293. ** UNROLLED version
  294. *)
  295.  
  296. PROCEDURE dscal_ur (n : INTEGER; da : FLOAT;
  297.                     VAR dx : FLOATARRAY; incx : INTEGER);
  298.  
  299. VAR i, m : INTEGER;
  300. BEGIN
  301.     IF n <= 0 THEN RETURN END;
  302.     IF incx <> 1 THEN
  303.  
  304.         (* code for increment not equal to 1 *)
  305.  
  306.         FOR i := 0 TO n-1 DO
  307.             dx[i*incx] := da*dx[i*incx];
  308.         END;
  309.         RETURN;
  310.     END;
  311.  
  312.     (* code for increment equal to 1 *)
  313.  
  314.     m := n MOD 5;
  315.     IF m <> 0 THEN
  316.         FOR i := 0 TO m-1 DO
  317.             dx[i] := da*dx[i];
  318.         END;
  319.         IF n < 5 THEN RETURN END;
  320.     END;
  321.     FOR i := m TO n-1 BY 5 DO
  322.         dx[i]   := da*dx[i];
  323.         dx[i+1] := da*dx[i+1];
  324.         dx[i+2] := da*dx[i+2];
  325.         dx[i+3] := da*dx[i+3];
  326.         dx[i+4] := da*dx[i+4];
  327.     END;
  328. END dscal_ur;
  329.  
  330. (*
  331. ** Finds the index of element having max. absolute value.
  332. ** Jack Dongarra, linpack, 3/11/78.
  333. *)
  334.  
  335. PROCEDURE idamax (n : INTEGER; VAR dx : FLOATARRAY; incx : INTEGER) : INTEGER;
  336.  
  337. VAR dmax         : FLOAT;
  338.     i, ix, itemp : INTEGER;
  339.  
  340. BEGIN
  341.     IF n < 1 THEN RETURN -1 END;
  342.     IF n = 1 THEN RETURN  0 END;
  343.     IF incx <> 1 THEN
  344.  
  345.         (* code for increment not equal to 1 *)
  346.  
  347.         ix := 1;
  348.         dmax := A